#include "OutlierDetector.h"
#include <cmath>
#include <algorithm>
#include <numeric>
#include <QDebug>

// 构造函数
OutlierDetector::OutlierDetector() {}

// 析构函数
OutlierDetector::~OutlierDetector() {}

// 主方法：定位异常值
QVector<bool> OutlierDetector::locateOutliers(const QVector<double>& t, const QVector<double>& s, const QString& method, double opt1, double opt2) {
    if (s.isEmpty())  {
        qWarning() << "Input array is empty";
        return QVector<bool>();
    }

    if (method == "percent") {
        return percentFilter(s, opt1);
    } else if (method == "sd") {
        return sdFilter(t, s, opt1);
    } else if (method == "thresh") {
        return threshFilter(s, (opt2 == 0) ? "above" : "below", opt1);
    } else if (method == "median") {
        return medianFilter(s, opt1);
    } else {
        qWarning() << "Unknown method:" << method;
        return QVector<bool>(s.size(),  false);
    }
}

// 百分比滤波器
QVector<bool> OutlierDetector::percentFilter(const QVector<double>& s, double perLimit) {
    QVector<bool> outliers(s.size(),  false);
    if (perLimit > 1) perLimit /= 100; // 如果输入是百分比，转换为小数

    for (int i = 1; i < s.size();  ++i) {
        double pChange = std::abs(s[i] - s[i - 1]) / s[i - 1]; // 计算百分比变化
        outliers[i] = (pChange > perLimit); // 判断是否为异常值
    }
    return outliers;
}

// 标准差滤波器
QVector<bool> OutlierDetector::sdFilter(const QVector<double>& t, const QVector<double>& s, double sdLimit) {
    QVector<bool> outliers(s.size(),  false);
    QVector<double> detrended = s; // 去趋势（这里简化处理，直接使用原数据）

    double mu = std::accumulate(detrended.begin(),  detrended.end(),  0.0) / detrended.size();  // 计算均值
    double sigma = 0.0;
    for (double val : detrended) {
        sigma += std::pow(val - mu, 2);
    }
    sigma = std::sqrt(sigma / detrended.size());  // 计算标准差

    for (int i = 0; i < s.size();  ++i) {
        outliers[i] = (std::abs(s[i] - mu) > sdLimit * sigma); // 判断是否为异常值
    }
    return outliers;
}

// 阈值滤波器
QVector<bool> OutlierDetector::threshFilter(const QVector<double>& s, const QString& type, double thresh) {
    QVector<bool> outliers(s.size(),  false);
    if (type == "above") {
        for (int i = 0; i < s.size();  ++i) {
            outliers[i] = (s[i] > thresh);
        }
    } else if (type == "below") {
        for (int i = 0; i < s.size();  ++i) {
            outliers[i] = (s[i] < thresh);
        }
    }
    return outliers;
}

// 中值滤波器
QVector<bool> OutlierDetector::medianFilter(const QVector<double>& s, double t) {
    QVector<bool> outliers(s.size(),  false);

    // 计算中值
    QVector<double> sorted = s; // 复制数据以避免修改原数据
    std::nth_element(sorted.begin(),  sorted.begin()  + sorted.size()  / 2, sorted.end());
    double sM = sorted[sorted.size() / 2];

    // 计算绝对偏差的中值 (MAD)
    QVector<double> absDiff;
    for (double val : s) {
        absDiff.push_back(std::abs(val  - sM));
    }
    std::nth_element(absDiff.begin(),  absDiff.begin()  + absDiff.size()  / 2, absDiff.end());
    double med = absDiff[absDiff.size() / 2];
    double D = med / 1.483; // 计算 MAD

    // 判断是否为异常值
    for (int i = 0; i < s.size();  ++i) {
        outliers[i] = (std::abs(s[i] - sM) / D > t);
    }
    return outliers;
}
